package com.grant.code.controller;

import com.grant.code.pojo.User;
import com.grant.code.service.UserService;
import com.grant.code.service.VideoService;
import com.grant.code.utils.DialogUtils;
import javafx.animation.PauseTransition;
import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.Dialog;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.TextInputDialog;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.TilePane;
import javafx.scene.layout.VBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.scene.paint.Color;
import javafx.scene.transform.Transform;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.util.Duration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 视频控制器 - 处理视频显示和操作的所有功能
 * 包括视频列表显示、播放、上传和删除等
 */
@Component
public class VideoController {

    @FXML private TilePane videoContainer;
    @FXML private Label statusBar;
    
    private VideoService videoService;
    private UserService userService;
    
    // 当前用户属性
    private final ObjectProperty<User> currentUserProperty = new SimpleObjectProperty<>();
    
    private final List<File> videoFiles = new ArrayList<>();
    private MediaPlayer currentMediaPlayer;
    
    // 视频文件扩展名集合
    private final Set<String> VIDEO_EXT = Set.of(".mp4", ".MP4", ".avi", ".AVI", ".mov", ".MOV", ".wmv", ".WMV", ".flv", ".FLV");
    
    // 允许的文件扩展名
    public static final String[] ALLOWED_EXTENSIONS = {
        ".mp4", ".avi", ".mov", ".wmv", ".flv"
    };
    
    /**
     * 默认构造函数
     */
    public VideoController() {
        // 用于JavaFX FXML注入
    }
    
    /**
     * 带参数的构造函数
     * @param videoContainer 视频容器
     * @param statusBar 状态栏
     * @param videoService 视频服务
     * @param userService 用户服务
     */
    public VideoController(TilePane videoContainer, Label statusBar, VideoService videoService, UserService userService) {
        this.videoContainer = videoContainer;
        this.statusBar = statusBar;
        this.videoService = videoService;
        this.userService = userService;
        
        initialize();
    }
    
    // 如果使用Spring Bean管理，可以使用此方法注入服务
    @Autowired
    public void setServices(VideoService videoService, UserService userService) {
        this.videoService = videoService;
        this.userService = userService;
    }
    
    /**
     * 设置当前用户并加载其视频
     * @param user 当前用户
     */
    public void setCurrentUser(User user) {
        if (user == null) {
            System.err.println("警告: 尝试设置空用户到视频控制器");
            return;
        }
        
        // 设置当前用户
        currentUserProperty.set(user);
        System.out.println("视频控制器: 设置用户 " + user.getUserName() + " (ID=" + user.getUserId() + ")");
        
        // 加载用户视频
        loadUserVideos();
    }
    
    /**
     * 加载当前用户的所有视频
     */
    public void loadUserVideos() {
        User currentUser = currentUserProperty.get();
        if (currentUser == null || videoService == null) {
            System.err.println("无法加载视频: 当前用户为空或视频服务未初始化");
            return;
        }
        
        // 确保用户视频目录存在
        try {
            videoService.initUserVideoDirectory(currentUser.getUserId());
        } catch (Exception e) {
            System.err.println("初始化用户视频目录失败: " + e.getMessage());
        }
        
        // 清空当前视频列表
        videoFiles.clear();
        
        try {
            // 加载用户视频
            List<File> userVideos = videoService.getUserVideos(currentUser.getUserId());
            videoFiles.addAll(userVideos);
            
            System.out.println("已加载 " + userVideos.size() + " 个视频文件");
            
            // 更新UI
            Platform.runLater(this::refreshVideoList);
        } catch (Exception e) {
            System.err.println("加载用户视频失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    /**
     * 初始化视频控制器
     */
    public void initialize() {
        // 视频容器可能为null，例如在FXML初始化完成之前
        if (videoContainer == null) {
            return;
        }
        
        // 设置拖放功能
        setupDragAndDrop();
        
        // 立即显示拖放提示，不等待异步执行
        if (videoFiles.isEmpty()) {
            videoContainer.getChildren().clear();
            showDragAndDropHint();
            if (statusBar != null) {
                statusBar.setText("提示：您可以拖放视频文件到此区域，或点击上传按钮");
            }
        }
        
        // 布局完成后的额外初始化
        Platform.runLater(() -> {
            // 再次检查，以防在异步执行前视频容器被设置为null
            if (videoContainer == null) return;
            
            if (videoContainer.getParent() != null && videoContainer.getParent().getParent() instanceof ScrollPane) {
                ScrollPane scrollPane = (ScrollPane) videoContainer.getParent().getParent();
                scrollPane.setOnDragOver(this::handleDragOver);
                scrollPane.setOnDragDropped(this::handleDragDrop);
                
                // 为了提高用户体验，添加视觉反馈
                scrollPane.setOnDragEntered(event -> {
                    if (event.getGestureSource() == null && event.getDragboard().hasFiles()) {
                        scrollPane.setStyle("-fx-background-color: rgba(52, 152, 219, 0.2);");
                        
                        // 如果视频容器为空，显示拖拽提示视觉反馈
                        if (videoFiles.isEmpty() && videoContainer.getChildren().size() == 1) {
                            Node hintBox = videoContainer.getChildren().get(0);
                            if (hintBox instanceof VBox) {
                                hintBox.setStyle("-fx-border-style: dashed; -fx-border-width: 3; -fx-border-color: #2ecc71; " + 
                                               "-fx-border-radius: 10; -fx-background-color: rgba(46, 204, 113, 0.1);");
                            }
                        }
                        
                        if (statusBar != null) {
                            statusBar.setText("释放鼠标以上传视频");
                        }
                    }
                    event.consume();
                });
                
                scrollPane.setOnDragExited(event -> {
                    scrollPane.setStyle(""); // 恢复原样式
                    
                    // 恢复提示框的原样式
                    if (videoFiles.isEmpty() && videoContainer.getChildren().size() == 1) {
                        Node hintBox = videoContainer.getChildren().get(0);
                        if (hintBox instanceof VBox) {
                            hintBox.setStyle("-fx-border-style: dashed; -fx-border-width: 3; -fx-border-color: #3498db; " + 
                                           "-fx-border-radius: 10; -fx-background-color: rgba(52, 152, 219, 0.05);");
                        }
                    }
                    
                    event.consume();
                });
            }
            
            // 为视频容器自身添加点击事件，在空白区域点击时调用上传方法
            videoContainer.setOnMouseClicked(event -> {
                if (videoFiles.isEmpty() && event.getTarget() == videoContainer) {
                    uploadVideo();
                }
            });
        });
    }
    
    /**
     * 设置拖拽上传功能
     */
    private void setupDragAndDrop() {
        videoContainer.setOnDragOver(this::handleDragOver);
        videoContainer.setOnDragDropped(this::handleDragDrop);
    }
    
    /**
     * 处理拖拽悬停事件
     * @param event 拖拽事件
     */
    private void handleDragOver(DragEvent event) {
        if (event.getGestureSource() == null && event.getDragboard().hasFiles()) {
            // 检查是否至少有一个有效的视频文件
            boolean hasValidVideoFile = event.getDragboard().getFiles().stream()
                    .anyMatch(this::isValidVideoFile);
            
            if (hasValidVideoFile) {
                event.acceptTransferModes(TransferMode.COPY);
                
                // 更新状态栏以提供反馈
                if (statusBar != null) {
                    statusBar.setText("释放鼠标以上传视频");
                }
            }
        }
        event.consume();
    }
    
    /**
     * 处理拖拽释放事件
     * @param event 拖拽事件
     */
    private void handleDragDrop(DragEvent event) {
        Dragboard db = event.getDragboard();
        boolean success = false;
        
        if (db.hasFiles()) {
            // 检查当前用户
            User currentUser = currentUserProperty.get();
            if (currentUser == null) {
                DialogUtils.showError("错误", "请先登录后再上传视频");
                event.consume();
                return;
            }
            
            List<File> validVideos = new ArrayList<>();
            
            // 处理所有拖放的文件
            for (File file : db.getFiles()) {
                if (isValidVideoFile(file)) {
                    validVideos.add(file);
                }
            }
            
            if (!validVideos.isEmpty()) {
                // 在后台线程中处理视频保存
                new Thread(() -> {
                    for (File file : validVideos) {
                        try {
                            // 通过视频服务保存文件，确保关联到当前用户
                            File savedVideo = videoService.saveUserVideo(currentUser.getUserId(), file);
                            
                            // 添加到视频列表，并刷新UI
                            videoFiles.add(savedVideo);
                            
                            Platform.runLater(() -> {
                                videoContainer.getChildren().add(createVideoCard(savedVideo));
                                statusBar.setText("成功上传视频: " + file.getName());
                            });
                        } catch (IOException e) {
                            Platform.runLater(() -> {
                                DialogUtils.showError("上传失败", "无法保存视频 " + file.getName() + ": " + e.getMessage());
                            });
                        }
                    }
                }).start();
                
                success = true;
            }
        }
        
        event.setDropCompleted(success);
        event.consume();
    }
    
    /**
     * 上传视频
     */
    @FXML
    public void uploadVideo() {
        // 检查当前用户
        User currentUser = currentUserProperty.get();
        if (currentUser == null) {
            DialogUtils.showError("错误", "请先登录后再上传视频");
            return;
        }
        
        // 配置文件选择器
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("选择视频文件");
        
        // 设置文件过滤器
        FileChooser.ExtensionFilter videoFilter = new FileChooser.ExtensionFilter(
                "视频文件", "*.mp4", "*.avi", "*.mov", "*.wmv", "*.flv");
        fileChooser.getExtensionFilters().add(videoFilter);
        
        // 获取用户选择的文件
        File selectedFile = fileChooser.showOpenDialog(videoContainer.getScene().getWindow());
        
        if (selectedFile != null && isValidVideoFile(selectedFile)) {
            try {
                // 显示上传进度
                if (statusBar != null) {
                    statusBar.setText("正在上传视频: " + selectedFile.getName() + "...");
                }
                
                // 通过视频服务保存文件，确保关联到当前用户
                File savedVideo = videoService.saveUserVideo(currentUser.getUserId(), selectedFile);
                
                // 添加到视频列表并刷新UI
                videoFiles.add(savedVideo);
                refreshVideoList();
                
                if (statusBar != null) {
                    statusBar.setText("成功上传视频: " + selectedFile.getName());
                }
            } catch (IOException e) {
                System.err.println("保存视频时出错: " + e.getMessage());
                DialogUtils.showError("上传失败", "无法保存视频: " + e.getMessage());
            }
        }
    }
    
    /**
     * 验证视频文件格式
     * @param file 视频文件
     * @return 是否为有效格式
     */
    private boolean isValidVideoFile(File file) {
        String fileName = file.getName().toLowerCase(); // 获取文件名并转换为小写
        for (String ext : ALLOWED_EXTENSIONS) {
            // 检查文件名是否以允许的扩展名结尾
            if (fileName.endsWith(ext)) return true; // 如果匹配，返回 true
        }
        return false; // 如果没有匹配，返回 false
    }
    
    /**
     * 刷新视频列表
     */
    @FXML
    public void refreshVideoList() {
        // 清空视频容器中的所有子节点
        videoContainer.getChildren().clear();
        
        // 如果视频列表为空，显示提示信息
        if (videoFiles.isEmpty()) {
            showDragAndDropHint();
            
            // 更新状态栏提示用户操作
            if (statusBar != null) {
                statusBar.setText("提示：您可以拖放视频文件到此区域，或点击上传按钮");
            }
        } else {
            // 遍历视频文件列表，为每个视频文件创建视频卡片并添加到容器中
            videoFiles.forEach(file -> videoContainer.getChildren().add(createVideoCard(file)));
            
            // 更新状态栏显示视频数量
            if (statusBar != null) {
                statusBar.setText("当前共有 " + videoFiles.size() + " 个视频文件");
            }
        }
    }
    
    /**
     * 显示拖拽上传提示
     */
    private void showDragAndDropHint() {
        // 创建外层容器，添加样式和效果
        VBox hintBox = new VBox(20);
        hintBox.setAlignment(Pos.CENTER);
        hintBox.setPrefWidth(Double.MAX_VALUE);
        hintBox.setPrefHeight(400); // 增加高度，提供更大的拖放区域
        hintBox.setStyle("-fx-border-style: dashed; -fx-border-width: 3; -fx-border-color: #3498db; " + 
                         "-fx-border-radius: 10; -fx-background-color: rgba(52, 152, 219, 0.05);");
        
        // 创建图标容器
        StackPane iconContainer = new StackPane();
        iconContainer.setPrefHeight(100);
        
        // 尝试加载上传图标
        ImageView uploadIcon = new ImageView();
        try {
            Image icon = new Image(getClass().getResourceAsStream("/images/upload-icon.png"));
            uploadIcon.setImage(icon);
        } catch (Exception e) {
            // 如果找不到图标，创建一个占位符
            uploadIcon.setImage(createUploadPlaceholderImage());
        }
        uploadIcon.setFitWidth(80);
        uploadIcon.setFitHeight(80);
        uploadIcon.setPreserveRatio(true);
        
        // 添加简单的上下动画效果
        final double originalY = 0;
        final double[] currentY = {originalY};
        
        // 定时动画任务，添加轻微的上下浮动效果
        javafx.animation.Timeline timeline = new javafx.animation.Timeline(
            new javafx.animation.KeyFrame(javafx.util.Duration.millis(1500), event -> {
                if (currentY[0] == originalY) {
                    // 向上移动
                    uploadIcon.setTranslateY(-10);
                    currentY[0] = -10;
                } else {
                    // 向下移动
                    uploadIcon.setTranslateY(originalY);
                    currentY[0] = originalY;
                }
            })
        );
        timeline.setCycleCount(javafx.animation.Animation.INDEFINITE);
        timeline.play();
        
        iconContainer.getChildren().add(uploadIcon);
        
        // 创建更明显的主标题
        Label hintLabel = new Label("拖放视频文件到此区域");
        hintLabel.setStyle("-fx-font-size: 24px; -fx-font-weight: bold; -fx-text-fill: #3498db;");
        
        // 添加辅助说明
        Label descriptionLabel = new Label("或点击下方按钮选择文件");
        descriptionLabel.setStyle("-fx-font-size: 16px; -fx-text-fill: #7f8c8d;");
        
        // 格式提示标签
        Label supportedFormatsLabel = new Label("支持格式：" + String.join(", ", ALLOWED_EXTENSIONS));
        supportedFormatsLabel.setStyle("-fx-font-size: 14px; -fx-text-fill: #95a5a6;");
        
        // 创建更吸引人的上传按钮
        Button uploadBtn = new Button("选择视频文件");
        uploadBtn.setOnAction(e -> uploadVideo());
        uploadBtn.setStyle("-fx-background-color: #3498db; -fx-text-fill: white; " + 
                          "-fx-font-weight: bold; -fx-font-size: 16px; -fx-padding: 10 20; " +
                          "-fx-background-radius: 5;");
        uploadBtn.setPrefWidth(200);
        
        // 添加鼠标悬停效果
        uploadBtn.setOnMouseEntered(e -> 
            uploadBtn.setStyle("-fx-background-color: #2980b9; -fx-text-fill: white; " + 
                              "-fx-font-weight: bold; -fx-font-size: 16px; -fx-padding: 10 20; " +
                              "-fx-background-radius: 5;")
        );
        uploadBtn.setOnMouseExited(e -> 
            uploadBtn.setStyle("-fx-background-color: #3498db; -fx-text-fill: white; " + 
                              "-fx-font-weight: bold; -fx-font-size: 16px; -fx-padding: 10 20; " +
                              "-fx-background-radius: 5;")
        );
        
        // 为容器本身添加拖放事件
        hintBox.setOnDragOver(this::handleDragOver);
        hintBox.setOnDragDropped(this::handleDragDrop);
        hintBox.setOnDragEntered(event -> {
            if (event.getGestureSource() == null && event.getDragboard().hasFiles()) {
                hintBox.setStyle("-fx-border-style: dashed; -fx-border-width: 3; -fx-border-color: #2ecc71; " + 
                                "-fx-border-radius: 10; -fx-background-color: rgba(46, 204, 113, 0.1);");
                if (statusBar != null) {
                    statusBar.setText("释放鼠标以上传视频");
                }
            }
            event.consume();
        });
        hintBox.setOnDragExited(event -> {
            hintBox.setStyle("-fx-border-style: dashed; -fx-border-width: 3; -fx-border-color: #3498db; " + 
                            "-fx-border-radius: 10; -fx-background-color: rgba(52, 152, 219, 0.05);");
            event.consume();
        });
        
        // 添加所有元素到容器
        hintBox.getChildren().addAll(iconContainer, hintLabel, descriptionLabel, supportedFormatsLabel, uploadBtn);
        videoContainer.getChildren().add(hintBox);
    }
    
    /**
     * 创建上传图标占位图
     * @return 上传图标图像
     */
    private Image createUploadPlaceholderImage() {
        WritableImage image = new WritableImage(100, 100);
        PixelWriter pixelWriter = image.getPixelWriter();
        
        // 底色
        Color bgColor = Color.TRANSPARENT;
        for (int y = 0; y < 100; y++) {
            for (int x = 0; x < 100; x++) {
                pixelWriter.setColor(x, y, bgColor);
            }
        }
        
        // 绘制圆形背景
        Color circleColor = Color.rgb(52, 152, 219, 0.2);
        int radius = 40;
        int centerX = 50;
        int centerY = 50;
        
        for (int y = 0; y < 100; y++) {
            for (int x = 0; x < 100; x++) {
                double distance = Math.sqrt(Math.pow(x - centerX, 2) + Math.pow(y - centerY, 2));
                if (distance <= radius) {
                    pixelWriter.setColor(x, y, circleColor);
                }
            }
        }
        
        // 绘制上传箭头
        Color arrowColor = Color.rgb(52, 152, 219);
        
        // 箭头杆
        for (int y = 40; y < 70; y++) {
            for (int x = 48; x < 52; x++) {
                pixelWriter.setColor(x, y, arrowColor);
            }
        }
        
        // 箭头头部
        for (int y = 25; y < 45; y++) {
            for (int x = 30; x < 70; x++) {
                // 创建一个向上的三角形
                if ((x >= 50 - (y - 25)) && (x <= 50 + (y - 25))) {
                    pixelWriter.setColor(x, y, arrowColor);
                }
            }
        }
        
        return image;
    }
    
    /**
     * 获取视频文件列表
     * @return 视频文件列表
     */
    public List<File> getVideoFiles() {
        return new ArrayList<>(videoFiles);
    }
    
    /**
     * 创建视频卡片
     * @param file 视频文件
     * @return 视频卡片组件
     */
    private VBox createVideoCard(File file) {
        VBox card = new VBox(10); // 创建一个垂直布局，设置间距
        card.getStyleClass().add("video-card"); // 添加样式类
        card.setPadding(new Insets(15)); // 设置内边距

        // 缩略图区域
        ImageView thumbnail = createThumbnailView(); // 创建视频缩略图视图
        loadThumbnailAsync(file, thumbnail); // 异步加载缩略图

        // 视频信息
        Label titleLabel = new Label(file.getName()); // 创建文件名标签
        titleLabel.setStyle("-fx-font-weight: 500; -fx-text-fill: #2c3e50;"); // 设置标签样式

        // 新增时长标签
        Label durationLabel = new Label(); // 创建时长标签
        durationLabel.setStyle("-fx-text-fill: #95a5a6;"); // 设置标签样式
        loadVideoDuration(file, durationLabel); // 新增方法加载视频时长

        // 操作按钮
        HBox buttonBar = createButtonBar(file); // 创建操作按钮栏

        // 将所有元素添加到视频卡片中
        card.getChildren().addAll(thumbnail, titleLabel, durationLabel, buttonBar);
        return card; // 返回创建好的视频卡片
    }
    
    /**
     * 创建缩略图视图
     * @return 缩略图视图组件
     */
    private ImageView createThumbnailView() {
        ImageView view = new ImageView();
        view.setFitWidth(280);
        view.setFitHeight(160);
        view.setPreserveRatio(true);
        view.setStyle("-fx-background-color: #ecf0f1; -fx-background-radius: 4;");
        return view;
    }
    
    /**
     * 创建按钮栏
     * @param file 视频文件
     * @return 按钮栏组件
     */
    private HBox createButtonBar(File file) {
        HBox box = new HBox(10); // 创建一个水平布局，设置子组件之间的间距
        box.setAlignment(Pos.CENTER); // 居中对齐按钮

        // 创建播放按钮，设置样式并添加事件处理
        Button playBtn = new Button("打开");
        playBtn.setStyle("-fx-text-fill: white; -fx-background-color: #3498db; -fx-font-weight: bold;"); // 设置按钮样式
        playBtn.setPrefWidth(60);
        playBtn.setOnAction(e -> playVideo(file)); // 设置播放按钮的事件处理逻辑

        // 创建重命名按钮
        Button renameBtn = new Button("重命名");
        renameBtn.setStyle("-fx-text-fill: white; -fx-background-color: #27ae60;"); // 设置绿色风格
        renameBtn.setPrefWidth(60);
        renameBtn.setOnAction(e -> renameVideo(file)); // 设置重命名按钮的事件处理逻辑

        // 创建删除按钮，设置样式并添加事件处理
        Button deleteBtn = new Button("删除");
        deleteBtn.setStyle("-fx-text-fill: white; -fx-background-color: #e74c3c;"); // 设置按钮样式
        deleteBtn.setPrefWidth(60);
        deleteBtn.setOnAction(e -> deleteVideo(file)); // 设置删除按钮的事件处理逻辑

        // 将所有按钮添加到按钮栏中
        box.getChildren().addAll(playBtn, renameBtn, deleteBtn);
        return box; // 返回创建好的按钮栏
    }
    
    /**
     * 检查是否为图片文件
     * @param file 文件
     * @return 是否为图片文件
     */
    private boolean isImageFile(File file) {
        String name = file.getName().toLowerCase(); // 获取文件名并转换为小写
        // 使用正则表达式检查文件扩展名是否为 jpg、jpeg、png 或 gif
        return name.matches(".*\\.(jpg|jpeg|png|gif)$");
    }
    
    /**
     * 异步加载视频时长
     * @param file 视频文件
     * @param label 时长标签
     */
    private void loadVideoDuration(File file, Label label) {
        // 检查文件是否为图像文件，如果是，则不执行后续操作
        if (isImageFile(file)) return;

        // 创建一个新的线程来异步处理视频时长的加载
        new Thread(() -> {
            try {
                // 创建Media对象，从文件URI加载视频
                Media media = new Media(file.toURI().toString());
                // 创建MediaPlayer对象以提取视频信息
                MediaPlayer extractor = new MediaPlayer(media);

                // 当MediaPlayer准备好时触发此回调
                extractor.setOnReady(() -> {
                    // 格式化视频时长并转换为可读的字符串格式
                    String duration = formatTime(extractor.getMedia().getDuration().toMillis());
                    // 更新UI线程中的标签，显示视频时长
                    Platform.runLater(() -> label.setText(duration));
                    // 释放MediaPlayer资源
                    extractor.dispose();
                });
            } catch (Exception e) {
                // 如果创建Media或MediaPlayer时发生异常，更新标签为"时长未知"
                Platform.runLater(() -> label.setText("时长未知"));
            }
        }).start(); // 启动新线程
    }
    
    /**
     * 格式化时间
     * @param millis 毫秒时间
     * @return 格式化后的时间字符串
     */
    private String formatTime(double millis) {
        millis /= 1000; // 将毫秒转换为秒
        String sec = String.format("%02d", (int)(millis % 60)); // 格式化秒数
        String min = String.format("%02d", (int)((millis / 60) % 60)); // 格式化分钟数
        return min + ":" + sec; // 返回格式化后的时间字符串
    }
    
    /**
     * 异步加载缩略图
     * @param file 视频文件
     * @param imageView 图片视图
     */
    private void loadThumbnailAsync(File file, ImageView imageView) {
        // 初始占位图
        imageView.setImage(createDefaultPlaceholder());

        Task<Image> task = new Task<>() {
            @Override
            protected Image call() {
                try {
                    // URI编码处理
                    String encodedPath = file.toURI().toString().replace(" ", "%20");
                    Media media = new Media(encodedPath);

                    // 同步机制改进
                    CompletableFuture<Image> imageFuture = new CompletableFuture<>();

                    Platform.runLater(() -> {
                        MediaPlayer mediaPlayer = new MediaPlayer(media);
                        MediaView mediaView = new MediaView(mediaPlayer);

                        mediaPlayer.setOnReady(() -> {
                            // 确保在FX线程执行
                            Platform.runLater(() -> {
                                try {
                                    // 精确控制快照参数
                                    mediaPlayer.seek(Duration.millis(
                                            mediaPlayer.getTotalDuration().toMillis() * 0.1
                                    ));

                                    mediaPlayer.play();
                                    mediaPlayer.pause();

                                    // 延迟确保帧渲染
                                    PauseTransition pause = new PauseTransition(Duration.millis(500));
                                    pause.setOnFinished(event -> {
                                        SnapshotParameters params = new SnapshotParameters();
                                        params.setFill(Color.TRANSPARENT);

                                        // 自适应缩放
                                        double scaleX = 280.0 / mediaView.getBoundsInLocal().getWidth();
                                        double scaleY = 160.0 / mediaView.getBoundsInLocal().getHeight();
                                        params.setTransform(Transform.scale(scaleX, scaleY));

                                        WritableImage snapshot = new WritableImage(280, 160);
                                        Image thumbnailImage = mediaView.snapshot(params, snapshot);

                                        // 释放资源
                                        mediaPlayer.dispose();

                                        // 完成future
                                        imageFuture.complete(thumbnailImage != null
                                                ? thumbnailImage
                                                : createDefaultPlaceholder());
                                    });
                                    pause.play();

                                } catch (Exception e) {
                                    imageFuture.complete(createDefaultPlaceholder());
                                }
                            });
                        });

//                        mediaPlayer.setOnError(imageFuture.complete(createDefaultPlaceholder());

                    });

                    // 等待结果，设置超时
                    return imageFuture.get(5, TimeUnit.SECONDS);

                } catch (Exception e) {
                    return createDefaultPlaceholder();
                }
            }
        };

        task.setOnSucceeded(event -> {
            Image result = task.getValue();
            if (result != null) {
                imageView.setImage(result);
            }
        });

        // 启动低优先级线程
        Thread thread = new Thread(task);
        thread.setDaemon(true);
        thread.setPriority(Thread.MIN_PRIORITY);
        thread.start();
    }

    private Image createDefaultPlaceholder() {
        // 简化占位图逻辑
        try {
            return new Image(getClass().getResourceAsStream("/images/video-placeholder.png"));
        } catch (Exception e) {
            // 创建纯色占位图
            WritableImage placeholder = new WritableImage(280, 160);
            GraphicsContext gc = new Canvas(280, 160).getGraphicsContext2D();
            gc.setFill(Color.DARKGRAY);
            gc.fillRect(0, 0, 280, 160);
            return placeholder;
        }
    }

    /**
     * 播放视频
     * @param file 视频文件
     */
    private void playVideo(File file) {
        try {
            // 更新状态栏
            statusBar.setText("正在使用系统默认播放器打开视频: " + file.getName());
            
            // 根据操作系统类型使用不同的命令打开视频文件
            String os = System.getProperty("os.name").toLowerCase();
            ProcessBuilder builder = null;
            
            if (os.contains("win")) {
                // Windows系统
                builder = new ProcessBuilder("cmd", "/c", "start", "", file.getAbsolutePath());
            } else if (os.contains("mac")) {
                // macOS系统
                builder = new ProcessBuilder("open", file.getAbsolutePath());
            } else if (os.contains("nix") || os.contains("nux")) {
                // Linux系统
                builder = new ProcessBuilder("xdg-open", file.getAbsolutePath());
            }
            
            if (builder != null) {
                builder.start();
            } else {
                // 显示错误提示
                Alert alert = new Alert(Alert.AlertType.ERROR);
                alert.setTitle("错误");
                alert.setHeaderText("不支持的操作系统");
                alert.setContentText("无法在当前操作系统上打开视频文件");
                alert.showAndWait();
                
                // 更新状态栏
                statusBar.setText("错误: 不支持的操作系统");
            }
        } catch (Exception e) {
            // 显示错误提示
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setTitle("错误");
            alert.setHeaderText("无法播放视频");
            alert.setContentText("播放视频时发生错误: " + e.getMessage());
            alert.showAndWait();
            
            // 更新状态栏
            statusBar.setText("错误: 无法播放视频 " + file.getName());
        }
    }
    
    /**
     * 删除视频
     * @param file 视频文件
     */
    private void deleteVideo(File file) {
        User currentUser = currentUserProperty.get();
        if (currentUser == null) {
            DialogUtils.showError("错误", "用户信息丢失，无法删除视频");
            return;
        }
        
        // 确认删除
        boolean confirmed = DialogUtils.showConfirmation(
                "确认删除", 
                "您确定要删除视频 " + file.getName() + " 吗?", 
                "此操作无法撤销。");
        
        if (confirmed) {
            try {
                // 通过视频服务删除文件
                boolean deleted = videoService.deleteUserVideo(currentUser.getUserId(), file.getName());
                
                if (deleted) {
                    // 从列表中移除并刷新UI
                    videoFiles.remove(file);
                    refreshVideoList();
                    
                    if (statusBar != null) {
                        statusBar.setText("已删除视频: " + file.getName());
                    }
                } else {
                    DialogUtils.showError("删除失败", "无法删除视频文件，请稍后重试");
                }
            } catch (Exception e) {
                System.err.println("删除视频时出错: " + e.getMessage());
                DialogUtils.showError("删除失败", "删除视频时发生错误: " + e.getMessage());
            }
        }
    }
    
    /**
     * 重命名视频
     * @param file 要重命名的视频文件
     */
    private void renameVideo(File file) {
        // 检查当前用户
        User currentUser = currentUserProperty.get();
        if (currentUser == null) {
            DialogUtils.showError("错误", "用户信息丢失，无法重命名视频");
            return;
        }
        
        // 获取原始文件名（不含路径）
        String originalFileName = file.getName();
        
        // 创建文本输入对话框
        TextInputDialog dialog = new TextInputDialog(getDisplayFileName(originalFileName));
        dialog.setTitle("重命名视频");
        dialog.setHeaderText("请输入新的视频名称");
        dialog.setContentText("新名称:");
        
        // 设置对话框图标和样式
        Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow();
        stage.getIcons().add(new Image(getClass().getResourceAsStream("/images/app-icon.png")));
        
        // 添加验证器，确保新名称不为空
        Button okButton = (Button) dialog.getDialogPane().lookupButton(ButtonType.OK);
        TextField input = dialog.getEditor();
        
        input.textProperty().addListener((observable, oldValue, newValue) -> {
            okButton.setDisable(newValue.trim().isEmpty() || containsInvalidChars(newValue));
        });
        
        // 显示无效字符提示
        Label invalidCharsLabel = new Label("文件名不能包含: / \\ : * ? \" < > |");
        invalidCharsLabel.setStyle("-fx-text-fill: #e74c3c;");
        invalidCharsLabel.setVisible(false);
        
        input.textProperty().addListener((observable, oldValue, newValue) -> {
            boolean invalid = containsInvalidChars(newValue);
            invalidCharsLabel.setVisible(invalid);
            okButton.setDisable(newValue.trim().isEmpty() || invalid);
        });
        
        // 将提示添加到对话框
        VBox content = new VBox(10);
        content.getChildren().addAll(input, invalidCharsLabel);
        dialog.getDialogPane().setContent(content);
        
        // 等待用户输入并处理结果
        dialog.showAndWait().ifPresent(newName -> {
            if (!newName.trim().isEmpty()) {
                try {
                    // 显示进度
                    if (statusBar != null) {
                        statusBar.setText("正在重命名视频...");
                    }
                    
                    // 执行重命名操作
                    File newFile = videoService.renameUserVideo(currentUser.getUserId(), originalFileName, newName);
                    
                    // 更新视频列表
                    int index = videoFiles.indexOf(file);
                    if (index >= 0) {
                        videoFiles.set(index, newFile);
                    }
                    
                    // 刷新UI
                    refreshVideoList();
                    
                    // 更新状态栏
                    if (statusBar != null) {
                        statusBar.setText("已重命名视频: " + originalFileName + " -> " + newFile.getName());
                    }
                } catch (IllegalArgumentException e) {
                    DialogUtils.showError("重命名失败", "无效的文件名: " + e.getMessage());
                } catch (IOException e) {
                    System.err.println("重命名视频时出错: " + e.getMessage());
                    e.printStackTrace();
                    DialogUtils.showError("重命名失败", "重命名视频文件时出错: " + e.getMessage());
                }
            }
        });
    }
    
    /**
     * 检查文件名是否包含无效字符
     * @param fileName 文件名
     * @return 是否包含无效字符
     */
    private boolean containsInvalidChars(String fileName) {
        return fileName.contains("/") || fileName.contains("\\") || 
               fileName.contains(":") || fileName.contains("*") || 
               fileName.contains("?") || fileName.contains("\"") || 
               fileName.contains("<") || fileName.contains(">") || 
               fileName.contains("|");
    }
    
    /**
     * 获取用于显示的文件名（不含UUID和扩展名）
     * @param fileName 原始文件名
     * @return 显示用文件名
     */
    private String getDisplayFileName(String fileName) {
        // 如果是UUID格式的文件名，返回一个友好的默认名称
        if (fileName.matches("[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\\..+")) {
            return "我的视频";
        }
        
        // 否则，返回不含扩展名的文件名
        int dotIndex = fileName.lastIndexOf('.');
        if (dotIndex > 0) {
            return fileName.substring(0, dotIndex);
        }
        return fileName;
    }
} 